const axios = require('axios');
const { v4: uuidv4 } = require('uuid');
const config = require('./config');

class ClusterManager {
    constructor(port) {
        this.port = port;
        this.currentNode = {
            id: uuidv4(),
            url: `http://localhost:${port}`,
            lastSeen: Date.now()
        };
        
        this.nodes = new Map();
        this.heartbeatTimer = null;
    }

    async init() {
        // 初始化节点列表
        await this.discoverNodes();
        
        // 启动心跳检测
        this.startHeartbeat();
        
        console.log(`集群管理器初始化完成，节点ID: ${this.currentNode.id}`);
    }

    async discoverNodes() {
        const nodes = config.cluster.nodes.filter(url => !url.includes(`:${this.port}`));
        
        for (const url of nodes) {
            try {
                const response = await axios.get(`${url}/health`, {
                    timeout: config.cluster.syncTimeout
                });
                
                if (response.status === 200) {
                    this.nodes.set(url, {
                        url,
                        lastSeen: Date.now(),
                        status: 'healthy'
                    });
                    console.log(`发现节点: ${url}`);
                }
            } catch (error) {
                console.warn(`节点 ${url} 无法连接:`, error.message);
            }
        }
    }

    getNodes() {
        return Array.from(this.nodes.values());
    }

    async syncSet(key, value, ttl) {
        const data = { key, value, ttl };
        const promises = [];
        
        for (const node of this.nodes.values()) {
            if (node.status === 'healthy') {
                promises.push(
                    this.retryOperation(
                        () => axios.post(`${node.url}/sync/set`, data, {
                            timeout: config.cluster.syncTimeout
                        }),
                        config.cluster.syncRetries
                    )
                );
            }
        }
        
        const results = await Promise.allSettled(promises);
        const successCount = results.filter(r => r.status === 'fulfilled').length;
        
        console.log(`同步写入完成: ${successCount}/${promises.length} 个节点成功`);
    }

    async syncDelete(key) {
        const data = { key };
        const promises = [];
        
        for (const node of this.nodes.values()) {
            if (node.status === 'healthy') {
                promises.push(
                    this.retryOperation(
                        () => axios.post(`${node.url}/sync/delete`, data, {
                            timeout: config.cluster.syncTimeout
                        }),
                        config.cluster.syncRetries
                    )
                );
            }
        }
        
        const results = await Promise.allSettled(promises);
        const successCount = results.filter(r => r.status === 'fulfilled').length;
        
        console.log(`同步删除完成: ${successCount}/${promises.length} 个节点成功`);
    }

    async retryOperation(operation, maxRetries) {
        let lastError;
        
        for (let i = 0; i < maxRetries; i++) {
            try {
                return await operation();
            } catch (error) {
                lastError = error;
                if (i < maxRetries - 1) {
                    await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
                }
            }
        }
        
        throw lastError;
    }

    startHeartbeat() {
        this.heartbeatTimer = setInterval(async () => {
            await this.checkNodeHealth();
        }, config.cluster.heartbeatInterval);
    }

    async checkNodeHealth() {
        const promises = [];
        
        for (const [url, node] of this.nodes.entries()) {
            promises.push(
                axios.get(`${url}/health`, {
                    timeout: 5000
                }).then(response => {
                    if (response.status === 200) {
                        node.lastSeen = Date.now();
                        node.status = 'healthy';
                    }
                }).catch(error => {
                    node.status = 'unhealthy';
                    console.warn(`节点 ${url} 心跳检测失败:`, error.message);
                })
            );
        }
        
        await Promise.allSettled(promises);
    }

    async close() {
        if (this.heartbeatTimer) {
            clearInterval(this.heartbeatTimer);
        }
    }
}

module.exports = ClusterManager;
